package pers.vic.blog.module.front.service.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import pers.vic.blog.constant.GlobalFieldParams;
import pers.vic.blog.module.api.model.BlogThirdUser;
import pers.vic.blog.constant.ThirdUserType;
import pers.vic.blog.constant.ThirdProperties;
import pers.vic.blog.module.front.service.AbstractAuthService;
import pers.vic.boot.base.craw.CrawlConnect;
import pers.vic.boot.base.exception.CommonException;
import pers.vic.boot.util.JsonUtil;

import java.io.IOException;
import java.util.Map;

/**
 * @author Vic.xu
 * @description: github 授权实现
 * @date: 2020/7/21 0021 17:57
 */
@Service
public class GithubAuthService extends AbstractAuthService {

    @Autowired
    private ThirdProperties thirdProperties;

    /**
     * 获取AccessToken   @link https://docs.github.com/en/developers/apps/authorizing-oauth-apps
     * @param code
     *
     * hub.com/login/oauth/access_token?client_id=${third.github.clientId}&client_secret=${third.github.clientSecret}&code=${code}&redirect_uri=${third.github.callback}&state=vic_${random.int[10000,20000]}
     * @return
     */
    @Override
    public String getAccessToken(String code) {
        ThirdProperties.ThirdAuthConfig config = config();
        CrawlConnect crawlConnect = CrawlConnect.build(config.getAccessTokenUrl()).validateTLSCertificates();
        crawlConnect.data("client_secret", config.getClientSecret());
        crawlConnect.data("code", code);
        crawlConnect.header("Accept", "application/json");
        String token = "";
        try {
            /*
            text 的数据格式
           {"access_token":"e72e16c7e42f292c6912e7710c838347ae178b4a", "scope":"repo,gist", "token_type":"bearer"}
             */
            String text = crawlConnect.postBodyText();
            logger.info("通过code[{}]获取授权码返回数据[{}]", code, text);
            return JsonUtil.jsonToObject(text, new TypeReference<Map<String, String>>() { }).get("access_token");
        } catch (IOException e) {
            logger.error(ExceptionUtils.getStackTrace(e));
            throw new CommonException("获取授权码出了点问题");
        }
    }

    /**
     * 根据授权码获取用户信息
     * @param accessToken
     * @return
     */
    @Override
    public BlogThirdUser getUserInfo(String accessToken) {
        CrawlConnect crawlConnect = CrawlConnect.build(config().getUserUrl()).validateTLSCertificates();
        crawlConnect.data("access_token", accessToken);
        crawlConnect.header("Accept", "application/json");
        //Authorization: token OAUTH-TOKEN
        crawlConnect.header("Authorization", "token " + accessToken);
        try {
             /*
            {
            "login": "xuduochoua",
            "id": 13197198,
            "node_id": "MDQ6VXNlcjEzMTk3MTk4",
            "avatar_url": "https://avatars3.githubusercontent.com/u/13197198?v=4",
            "gravatar_id": "",
            "url": "https://api.github.com/users/xuduochoua",
            "html_url": "https://github.com/xuduochoua",
            "followers_url": "https://api.github.com/users/xuduochoua/followers",
            "following_url": "https://api.github.com/users/xuduochoua/following{/other_user}",
            "gists_url": "https://api.github.com/users/xuduochoua/gists{/gist_id}",
            "starred_url": "https://api.github.com/users/xuduochoua/starred{/owner}{/repo}",
            "subscriptions_url": "https://api.github.com/users/xuduochoua/subscriptions",
            "organizations_url": "https://api.github.com/users/xuduochoua/orgs",
            "repos_url": "https://api.github.com/users/xuduochoua/repos",
            "events_url": "https://api.github.com/users/xuduochoua/events{/privacy}",
            "received_events_url": "https://api.github.com/users/xuduochoua/received_events",
            "type": "User",
            "site_admin": false,
            "name": null,
            "company": null,
            "blog": "",
            "location": null,
            "email": null,
            "hireable": null,
            "bio": null,
            "twitter_username": null,
            "public_repos": 21,
            "public_gists": 0,
            "followers": 0,
            "following": 2,
            "created_at": "2015-07-06T08:53:36Z",
            "updated_at": "2020-07-28T08:11:10Z",
            "private_gists": 0,
            "total_private_repos": 0,
            "owned_private_repos": 0,
            "disk_usage": 152,
            "collaborators": 0,
            "two_factor_authentication": false,
            "plan": {
                "name": "free",
                "space": 976562499,
                "collaborators": 0,
                "private_repos": 10000
            }
        }

             */
            String text = crawlConnect.getBodyText();
            Map<String, Object> result = JsonUtil.jsonToObject(text, new TypeReference<Map<String, Object>>() {});
            BlogThirdUser user = new BlogThirdUser();
            user.setAvatar(String.valueOf(result.get("avatar_url")));
            user.setType(ThirdUserType. gitee.name());
            user.setIdentifier(String.valueOf(result.get("login")));
            user.setNickname(String.valueOf(result.get("name")));
            logger.info("accessToken[{}]获取用户信息返回数据[{}]", accessToken, text);
            return user;
        } catch (IOException e) {
            logger.error(ExceptionUtils.getStackTrace(e));
            throw new CommonException("获取账户信息出了点问题");
        }
    }

    @Override
    public ThirdProperties.ThirdAuthConfig config() {
        return thirdProperties.getConfigByType(GlobalFieldParams.ThirdTypeEnum.github.name());
    }
}
